#include <sys/socket.h>     // 包含socket()、bind()、connect()等函数声明
#include <netinet/in.h>     // 包含AF_INET、SOCK_STREAM等常量定义
#include <arpa/inet.h>      // 包含inet_addr()等IP地址处理函数（如果需要）
#include <unistd.h>         // 包含close()函数

#include <cstdio>
#include <cstring>          // 提供std::strerror
#include <string>
using std::string;

inline bool ret_check(int ret, const string& msg = "", bool should_exit = true)
    { 
        if(ret < 0){
            char message[256];
            
            snprintf(message, sizeof(message), 
                     "%s | %d | %s | error : %s\n | errno = %d(%s) \n", 
                     (const char*)__FILE__, __LINE__, __FUNCTION__, msg.c_str(), errno, std::strerror(errno));
            perror(message);
            
            if(should_exit)
            {
                exit(EXIT_FAILURE);
            }
            return false;
        } 
        return true;
    }

bool test(){
    int ret = 0;
    
    // 1. 创建套接字(与服务器相同)
    int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    ret_check(socket_fd, "socket failed");

    // 2. 连接到服务器（替换bind和listen）
    struct sockaddr_in server_addr = {0};
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");   // 服务器IP（必须指定
    server_addr.sin_port = htons(8080);                     // 服务器端口

    // 注意结构体名称，是sock_addr*而不是sockaddr
    ret = connect(socket_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
    ret_check(ret, "connect failed");

    printf("Connected to server at 127.0.0.1:8080 \n");

    // 3. 客户端开始发送/ 接收数据
    const char* msg = "Hello, server!";
    ret = send(socket_fd, msg, strlen(msg), 0);
    ret_check(ret, "send failed");
    printf("Sent: %s\n", msg);

    // 4. 接收服务器响应
    char buffer[1024] = {0};
    ret = recv(socket_fd, buffer, sizeof(buffer), 0);
    if(ret > 0)
    {
        printf("Received: %s\n", buffer);
    }

    close(socket_fd);
    return 0;
}

int main()
{
    test();
    return 0;
}

